﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClassFolio.Model;

namespace ClassFolio.Dict
{
	public class Dept
	{
		#region Работа с департаментами

		/// <summary>
		/// Создается новый экземпляр класса Dept
		/// </summary>
		/// <param name="name">Имя департамента.</param>
		/// <returns>Если запись создана в справочнике возвращается экземпляр класса, если нет, генерируется 
		/// исключение</returns>
		/// <exception cref="EFolioSource">Исключение возникает при попытке создать запись с неуникальным именем
		/// департамента</exception>
		/// <remarks>Длина поля SHORT_NAME не может превышать 32 символов, а длина поля FULL_NAME - 128. 
		/// Система автоматически отслеживает ограничение, обрезая до указанного количества символов слишком
		/// большие строки</remarks>
		public static Dept CreateDept(string shortName, string fullName)
		{
			return DeptGate.ApplyToDb(Dept.LogonUser.ID, new Dept(0) { ShortName = shortName, FullName = fullName });
		}

		/// <summary>
		/// Создается экземпляр класса Departments. Данные загружаются из базы по идентификатору
		/// </summary>
		/// <param name="deptId">Идентификатор департамента</param>
		/// <returns>Если все прошло удачно, возвращается созданный экземпляр класса. В другом случае 
		/// генерируется исключение</returns>
		/// <exception cref="EFolioSource">Исключительная ситуация возникает тогда, когда для переданного 
		/// идентификатора в базе не нашлось сооответсвующей записи</exception>
		public static Dept LoadDept(int deptId)
		{
			return DeptGate.RefreshFromDb(new Dept(deptId));
		}

		/// <summary>
		/// Удаление департамента из базы данных
		/// </summary>
		/// <param name="dept">Экземпляр класса, который будет удален</param>
		public static void RemoveDept(Dept dept)
		{
			DeptGate.RemoveDept(LogonUser.ID, dept.ID);
		}

		/// <summary>
		/// Проверяется наличие в базе данных соответствующего департамента
		/// </summary>
		/// <param name="dept">Экземпляр класса Dept, наличие которого в базе необходимо проверить</param>
		/// <returns>Если департамент существует возвращается True, иначе False</returns>
		public static bool DeptExist(Dept dept)
		{
			return DeptGate.DeptExist(dept.ID);
		}

		/// <summary>
		/// Значения свойств класса сохраняются в базе данных
		/// </summary>
		public void ApplyToDb()
		{
			DeptGate.ApplyToDb(LogonUser.ID, this);
		}

		/// <summary>
		/// Обновление значений свойств класса значениями из базы данных
		/// </summary>
		public void RefreshFromDb()
		{
			DeptGate.RefreshFromDb(this);
		}

		#endregion

		#region Выборки

		/// <summary>
		/// Выборка из базы данных. Содержит поля "ID", "NAME", "SURNAME"
		/// </summary>
		/// <param name="swth">Экземпляр класса фильтра записей</param>
		/// <returns>Выборка полученная из базы, в соответствии с примененным фильтром</returns>
		public static Sequence GetSequence(SqlSwitch swth)
		{
			return DeptGate.GetSequence(swth);
		}

		#endregion

		#region Properties

		/// <summary>
		/// Идентификатор департамента в базе данных
		/// </summary>
		public int ID { get { return this._id; } }
		
		/// <summary>
		/// Краткое наименование организации
		/// </summary>
		public string ShortName
		{
			get { return this._shortName; }
			set
			{
				if (String.IsNullOrEmpty(value))
					throw new EFolio(0, MessageType.UserMessage, Messages.dp_empty_shname, null);
				else
					this._shortName = Tools.SubStr(value, 32);
			}
		}
		
		/// <summary>
		/// Полное наименование организации
		/// </summary>
		public string FullName
		{
			get { return this._fullName; }
			set
			{
				if (String.IsNullOrEmpty(value))
					throw new EFolio(0, MessageType.UserMessage, Messages.dp_empty_flname, null);
				else
					this._fullName = Tools.SubStr(value, 128);
			}
		}

		/// <summary>
		/// Шлюз таблицы
		/// </summary>
		/// <remarks>
		/// Значение свойству присваивается во время инициализации системы функцией 
		/// <see cref="LoginAs"/> класса <see cref="GeneFolio.AreaWork.AreaWork"/>
		/// </remarks>
		public static IDeptGate DeptGate { get; set; }

		/// <summary>
		/// Текущий пользователь подключенный к базе
		/// </summary>
		/// <remarks>
		/// Значение свойству присваивается во время инициализации системы функцией 
		/// <see cref="LoginAs"/> класса <see cref="GeneFolio.AreaWork.AreaWork"/>
		/// </remarks>
		public static User LogonUser { get; set; }

		#endregion

		#region Private

		private Dept(int deptId)
        {
			this._id = deptId;
        }
		private int _id;
		private string _shortName;
		private string _fullName;

		#endregion
	}

	public interface IDeptGate
	{
		void RemoveDept(int activeUserId, int deptId);
		Dept ApplyToDb(int activeUserId, Dept dept);
		Dept RefreshFromDb(Dept dept);
		bool DeptExist(int deptId);

		// Работа с наборами данных
		Sequence GetSequence(SqlSwitch swth);
	}
}
